using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;
using MrDev.Graphics;
using MrDev.GameMath;
using MrDev.Physics;

namespace MrDev.GameObjects
{
    /// <summary>
    /// Our fearless adventurer!
    /// </summary>
    class Boss1 : Boss
    {
        private Animation bossAnimation;
        private float shootCoolDown = 0;
        private Vector2 spawnPosition;
        private float faceCoolDown = 0;
        private int face = 0;
        private float radians = 0;
        private Vector2 shotVelocity = new Vector2(1, 0);
        private Vector2 basePosition;
        private float hitCounter;
        private double floatTime = 0;
        /// <summary>
        /// Constructors a new player.
        /// </summary>
        public Boss1(Level level, Vector2 position)
            : base(level)
        {
            basePosition = position;
            this.Level = level;
            this.spawnPosition = position;
            LoadContent();
            Initialize();
            SetColor(Color.White);
        }

        public override void Initialize()
        {
            if (initialized || !IsAlive)
                return;
            LoadContent();
            Parameters = PhysicsParameters.CreateBoss1Parameters();
            Parameters.RelativeCollisionRect = new Rectangle(
                128, 0, 48, 60);
            Bullets = new List<Bullet>();
            Reset(spawnPosition);
            faceCoolDown = 0;
            face = 0;
            radians = 0;
            shotVelocity = new Vector2(1, 0);
            Lives = 50;
        }

        /// <summary>
        /// Loads the player sprite sheet and sounds.
        /// </summary>
        public void LoadContent()
        {
            // Load animated textures.
            bossAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/Bosses/boss1"), 0.1f, true, 0, 1);
            bossAnimation.FrameHeight = bossAnimation.Texture.Height;
            bossAnimation.FrameWidth = bossAnimation.Texture.Width;
        }

        /// <summary>
        /// Resets the player to life.
        /// </summary>
        /// <param name="position">The position to come to life at.</param>
        public void Reset(Vector2 position)
        {
            Level.Physics.SetObjectPosition(this, position);
            SetColor(Color.White);
            IsAlive = true;
            PlayAnimation(bossAnimation);
        }

        /// <summary>
        /// Handles input, performs physics, and animates the player sprite.
        /// </summary>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            if (IsAlive)
            {
                BossAction(gameTime);
            }

            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;


            floatTime += elapsedTime;
            Parameters.Position = basePosition + new Vector2(0, (float)Math.Sin(floatTime * 10) * 10);


            BossLifeText[] lifeTextsCopy = lifeTexts.ToArray();
            for (int i = 0; i < lifeTextsCopy.Length; i++)
            {
                BossLifeText lifeText = lifeTextsCopy[i];
                lifeText.Progress -= elapsedTime;
                if (lifeText.Progress < 0f)
                {
                    lifeTexts.Remove(lifeText);
                }
                lifeText.Position += new Vector2(2f * (float)Math.Cos(lifeText.Progress * 2 * Math.PI), -100f * elapsedTime);
            }

            List<Bullet> killedBullets = new List<Bullet>();

            foreach (Bullet b in Bullets)
            {
                b.Update(gameTime);
                if (!b.IsAlive)
                    killedBullets.Add(b);
                else
                {
                    Vector2 collisionDepth = RectangleExtensions.GetIntersectionDepth(Level.Physics.AbsoluteCollisionRect(Level.Player), Level.Physics.AbsoluteCollisionRect(b));
                    if (collisionDepth != Vector2.Zero)
                    {
                        Level.Player.Kill();
                        break;
                    }
                }
            }

            foreach (Bullet b in killedBullets)
            {
                Bullets.Remove(b);
            }
        }

        public override void Hit()
        {
            Rectangle rect = Level.Physics.AbsoluteCollisionRect(this);
            Vector2 position = new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height);
            lifeTexts.Add(new BossLifeText() { distance = 20, Progress = 2f, Text = Lives.ToString(), Position = position });
            Lives--;
            hitCounter = 0.1f;
            if (Lives == 0)
            {
                IsAlive = false;
                StartBlinkMode(2f);

                Level.ExplodeInsane(new Rectangle(
                    (int)Parameters.Position.X - Parameters.SpriteSize.Width / 2,
                    (int)Parameters.Position.Y - Parameters.SpriteSize.Height,
                    Parameters.SpriteSize.Width,
                    Parameters.SpriteSize.Height),
                    100);
            }
            else
                Level.Explode(position);
        }

        /// <summary>
        /// Gets boss actions
        /// </summary>
        /// 
        private void BossAction(GameTime gameTime)
        {
            if (hitCounter > 0)
            {
                hitCounter -= (float)gameTime.ElapsedGameTime.TotalSeconds;
            }
            else
            {
                hitCounter = 0;
            }


            if (faceCoolDown > 0)
                faceCoolDown -= (float)gameTime.ElapsedGameTime.TotalSeconds;
            else
                faceCoolDown = 0;

            if (faceCoolDown == 0)
            {
                face = (face + 1) % 4;
                faceCoolDown = 2f;

                if (face == 0)
                    radians = 0 * (float)Math.PI / 6f;
                else if (face == 1)
                    radians = 1 * (float)Math.PI / 6f;
                else if (face == 2)
                    radians = 2 * (float)Math.PI / 6f;
                else if (face == 3)
                    radians = 3 * (float)Math.PI / 6f;

            }

            if (shootCoolDown > 0)
                shootCoolDown -= (float)gameTime.ElapsedGameTime.TotalSeconds;
            else
            {
                shootCoolDown = 0;
                if (radians > 2f * (float)Math.PI)
                    radians -= 2f * (float)Math.PI;
                radians += 0.05f;
                shotVelocity = new Vector2((float)Math.Cos(radians), (float)Math.Sin(radians));
                Shoot(shotVelocity * 600f);
                shootCoolDown = 0.1f;
            }
        }

        private void Shoot(Vector2 velocity)
        {
            //SpawnBullet(bulletStartPosition, bulletDirection, bulletSpeed);
            Bullet b = new Bullet(Level, new Vector2(Parameters.Position.X, Parameters.Position.Y - Parameters.SpriteSize.Height + 24));
            b.Parameters.Movement = 0;
            b.Parameters.Velocity = velocity;
            Bullets.Add(b);

        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            base.Draw(gameTime, spriteBatch);
            foreach (Bullet b in Bullets)
            {
                b.Draw(gameTime, spriteBatch);
            }
            DrawLifeText(gameTime, spriteBatch);
        }
    }
}
